using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.CodeDom.Compiler;
using System.Diagnostics;
using LiveCode.LiveInterface;

namespace LiveCode.LiveApp
{
    public partial class OpenRobotEngine : Form
    {
        /// <summary>
        /// Application Domain Variables.
        /// </summary>
        public AppDomain secDom;
        public LiveInterfaceFactory factory;
        public ILiveInterface ilive;
        private bool secDomainLoaded = false, bSourceOpen = false, bCodeChanged = false, bRobotConnected = false;

        /// <summary>
        /// Various other variables.
        /// </summary>
        private string strFileName = string.Empty;
        private string strAppDir = string.Empty;
        public string robotTemplate = string.Empty;
        public string robotVirtualTemplate = string.Empty;
        public bool stopRobot = false, bBeginnerMode = true;
        private int intCurCodeLine = 0, timeOutms = 0, numRetries = 0;

        /// <summary>
        /// Task Thread Variable.
        /// </summary>
        public Thread trd, trdRobot;

        /// <summary>
        /// This delegate enables asynchronous calls for setting the text property 
        /// on a TextBox control.
        /// </summary>
        /// <param name="text">text to set on control.</param>
        delegate void SetTextCallback(string text);

        public OpenRobotEngine()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Form Load Event. Read in source code template and get current directory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenRobotEngine_Load(object sender, EventArgs e)
        {
            //Get Application Directory.
            strAppDir = Directory.GetCurrentDirectory();

            //Read in the open_robot_template.cs file.
            Read_Source_Code();

            timeOutms = Convert.ToInt16(nmbTimeOutms.Value);
            numRetries = Convert.ToInt16(nmbNumRetries.Value);

            bRobotConnected = false;
        }

        /// <summary>
        /// Open-Robot form closing event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenRobotEngine_FormClosing(object sender, FormClosingEventArgs e)
        {
            //If the 2nd AppDomain is loaded, Unload it!
            if (secDomainLoaded) Unload_AppDomain();

            //If the user has open code that has changed, ask to save it.
            if (bSourceOpen && bCodeChanged) Ask_User_To_Save();
        }

        

        // Code Engine Functions //////////////////////////////////////////////                                          

        /// <summary>
        /// Function to Highlight Compiler Errors in the Full Code Screen.
        /// </summary>
        private void Highlight_Compile_Error(int Line)
        {
            rdoFullCode.Checked = true;
            this.Refresh();
            int offset = 0, lineLength = 0;
            for (int i = 0; i < Line - 1 && i < rtfFullCode.Lines.Length; i++)
            {
                offset += rtfFullCode.Lines[i].Length + 1;
            }
            lineLength = rtfFullCode.Lines[Line - 1].Length;
            rtfFullCode.Focus();
            rtfFullCode.Select(offset, lineLength);
            rtfFullCode.Refresh();
        }

        /// <summary>
        /// Thread safe method for setting txtRobotOutput TextBox.
        /// </summary>
        /// <param name="newText">New Text to set.</param>
        private void AddRobotOutputText(string newText)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.txtRobotOutput.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(AddRobotOutputText);
                this.Invoke(d, new object[] { newText });
            }
            else
            {
                string oldText = txtRobotOutput.Text;
                if (oldText == string.Empty) this.txtRobotOutput.Text = newText;
                else this.txtRobotOutput.Text = oldText + System.Environment.NewLine + newText;
            }
        }

        /// <summary>
        /// Thread safe method for setting txtErrors TextBox.
        /// </summary>
        /// <param name="newText">New Text to set.</param>
        private void AddErrorText(string newText)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.txtErrors.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(AddErrorText);
                this.Invoke(d, new object[] { newText });
            }
            else
            {
                string oldText = txtErrors.Text;
                if (oldText == string.Empty) this.txtErrors.Text = newText;
                else this.txtErrors.Text = newText + System.Environment.NewLine + oldText;
            }
        }

        /// <summary>
        /// Function to Compile the code into an executable DLL.
        /// </summary>
        private void DoCompile()
        {
            try
            {
                //First populate the Full Code rich textbox.
                Populate_Full_Code();

                // Define the required source code.
                string[] srcCodes = new string[] { rtfFullCode.Text };
                // Define the referenced assemblies.
                string[] referAsm = new string[] { "LiveInterface.dll", "Fuzzy_Logic_Lib_Desktop.dll", "OPEN_ROBOT_TCP_Class_Library.dll", "OPEN_ROBOT_Virtual_TCP_Library.dll" };

                string outFile = strAppDir + "\\RobotAssembly.dll";	// the assembly to create.

                // compile the C# source now:
                // NOTE: this needs the multithreaded apartment => [MTAThread]
                CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");

                System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
                parameters.GenerateExecutable = false;
                parameters.OutputAssembly = outFile;
                // Add the referenced assemblies.
                for (int paramIndex = 0; paramIndex < referAsm.Length; paramIndex++)
                {
                    parameters.ReferencedAssemblies.Add(referAsm[paramIndex]);
                }
                CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, srcCodes);

                if (results.Errors.Count > 0)
                {	// create exception for compiler errors
                    string msg = "CompilerError[s] :\n";

                    //Highlight first error!
                    int lineNumber = results.Errors[0].Line;
                    if (lineNumber > 0) Highlight_Compile_Error(results.Errors[0].Line);

                    // Go through and extract each compiler error.
                    foreach (CompilerError CompErr in results.Errors)
                        msg += String.Format("line:{0} error:{1} '{2}'\n", CompErr.Line, CompErr.ErrorNumber, CompErr.ErrorText);
                    AddErrorText(msg);
                }
                else
                {
                    AddErrorText("Successfull Compile");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Function to Unload the Second Application Domain.
        /// </summary>
        private void Unload_AppDomain()
        {
            mnuFuzzyLogic.Enabled = false;
            mnuCode_Run.Enabled = false;
            mnuCode_Unload.Enabled = false;
            mnuCode_Load.Enabled = true;
            mnuCode_Compile.Enabled = true;
            secDomainLoaded = false;

            //Disconnect from robot.
            if (bRobotConnected) ilive.DisconnectFromRobot();
            bRobotConnected = false;
            mnuRobotDisconnect.Enabled = false;
            mnuRobotConnect.Enabled = false;
            mnuCode_Halt.Enabled = false;

            // release all references to the factory and ILiveInterface
            factory = null;
            ilive = null;

            // unload the complete secondary app-domain
            AppDomain.Unload(secDom);
        }

        /// <summary>
        /// Function to read in source code template.
        /// </summary>
        private void Read_Source_Code()
        {
            try
            {
                if (!File.Exists(strAppDir + "\\open_robot_template.cs"))
                {
                    MessageBox.Show("Missing open_robot_template.cs file!" + System.Environment.NewLine + "Program will now terminate!", "Missing open_robot_template file");
                    this.Close();
                    return;
                }
                StreamReader fi = new StreamReader(strAppDir + "\\open_robot_template.cs", Encoding.Default);
                robotTemplate = fi.ReadToEnd();
                fi.Close();

                if (!File.Exists(strAppDir + "\\open_robot_virtual_template.cs"))
                {
                    MessageBox.Show("Missing open_robot_virtual_template.cs file!" + System.Environment.NewLine + "Program will now terminate!", "Missing open_robot_virtual_template file");
                    this.Close();
                    return;
                }
                fi = new StreamReader(strAppDir + "\\open_robot_virtual_template.cs", Encoding.Default);
                robotVirtualTemplate = fi.ReadToEnd();
                fi.Close();
            }
            catch (Exception fe)
            {
                MessageBox.Show(fe.Message);
            }
        }

        /// <summary>
        /// Function to populate the full code text box.
        /// </summary>
        private void Populate_Full_Code()
        {
            char[] chrArray;
            string[] strArray;
            int numLines = 0, i, intIndex = 0;

            chrArray = textSourceCode.Text.ToCharArray();
            numLines = textSourceCode.Lines.Length;

            if (ckbUseVirtualRobot.Checked) rtfFullCode.Text = robotVirtualTemplate + System.Environment.NewLine;
            else rtfFullCode.Text = robotTemplate + System.Environment.NewLine;

            if (chrArray.Length > 0)
            {
                strArray = new string[numLines];
                strArray[0] = "		";
                for (i = 0; i < chrArray.Length; i++)
                {
                    strArray[intIndex] += chrArray[i];
                    if (chrArray[i] == Convert.ToChar(10))
                    {
                        intIndex += 1;
                        if (intIndex > numLines) break;
                        strArray[intIndex] = "		";
                    }
                }
                for (i = 0; i < numLines; i++)
                {
                    rtfFullCode.Text += strArray[i];
                }
            }
            rtfFullCode.Text += System.Environment.NewLine + "	}" + System.Environment.NewLine;
            rtfFullCode.Text += "}" + System.Environment.NewLine;
        }

        /// <summary>
        /// Function to Save the user's Code to a text file.
        /// </summary>
        /// <param name="strName"></param>
        private void Save_Code(string strName)
        {
            try
            {
                StreamWriter fi = new StreamWriter(strName, false, Encoding.Default);
                if (!bBeginnerMode) fi.Write(textSourceCode.Text);
                else fi.Write(txtCodeBuilder.Text);
                fi.Close();
                bCodeChanged = false;
                OpenRobotEngine.ActiveForm.Text = "Open-Robot Code Engine: " + strFileName;
            }
            catch (Exception fe)
            {
                MessageBox.Show(fe.Message);
                return;
            }
        }

        /// <summary>
        /// Function to check whether or not user wants to save code.
        /// </summary>
        /// <returns>bool</returns>
        private bool Ask_User_To_Save()
        {
            DialogResult dr = MessageBox.Show("Would You Like To Save your Code?", "Save Code?", MessageBoxButtons.YesNoCancel);
            switch (dr)
            {
                case DialogResult.Yes:
                    if (bSourceOpen && strFileName != "")
                    {
                        if (File.Exists(strFileName)) Save_Code(strFileName);
                    }
                    else
                    {
                        if (saveFileDialog1.ShowDialog().ToString() == "Cancel") return false;
                        strFileName = saveFileDialog1.FileName;
                        Save_Code(strFileName);
                    }
                    break;
                case DialogResult.No: return true;
                case DialogResult.Cancel: return false;
            }
            return true;
        }

        /// <summary>
        /// Robot Thread Task.
        /// </summary>
        private void RunRobotThreadTask()
        {
            while (!stopRobot)
            {
                // Call the 'LiveClass' instance method using our ILiveInterface
                string mainOutput = ilive.Main();
                AddRobotOutputText(mainOutput);

                if (mainOutput == "READ_ERROR" || mainOutput == "SETUP_FIS")
                {
                    mnuCode_Unload.Enabled = true;
                    mnuCode_Run.Enabled = true;
                    AddErrorText("Code Stopped");
                    stopRobot = true;
                    MessageBox.Show(mainOutput);
                    return;
                }
            }
            if (stopRobot)
            {
                ilive.StopRobot(timeOutms, numRetries);
                mnuCode_Unload.Enabled = true;
                mnuCode_Run.Enabled = true;
                AddErrorText("Code Stopped");
                return;
            }
        }

        /// <summary>
        /// Function to insert code at the selected line number.
        /// </summary>
        /// <param name="strCode"></param>
        /// <param name="intLineNumber"></param>
        private void Insert_Code(string strCode)
        {
            string[] strLines = txtCodeBuilder.Lines;
            string strTmpCode = String.Empty;
            int intEndLine = -1, i = 0, intNewEndLine = 0;

            if ((intCurCodeLine < strLines.Length - 1))
            {
                intEndLine = Get_End_Line_Of_Code_Block(strLines, intCurCodeLine);
                if (intEndLine < 0)
                {
                    if (intEndLine == -2) MessageBox.Show("Select Start of Code Block for Insertion");
                    else MessageBox.Show("Error Inserting Code!");
                    return;
                }
                for (i = 0; i < intCurCodeLine; i++) if (strLines[i] != "") strTmpCode += strLines[i] + System.Environment.NewLine;
                strTmpCode += strCode;
                txtCodeBuilder.Text = strTmpCode;
                intNewEndLine = txtCodeBuilder.Lines.Length - 1;
                for (i = intCurCodeLine; i < strLines.Length; i++) if (strLines[i] != "") strTmpCode += strLines[i] + System.Environment.NewLine;
                txtCodeBuilder.Text = strTmpCode;
            }
            else
            {
                txtCodeBuilder.Text += strCode;
                intNewEndLine = txtCodeBuilder.Lines.Length;
            }

            intCurCodeLine = intNewEndLine;
            txtCodeBuilder.Focus();
            int intNewLength = 0;
            for (i = 0; i < intNewEndLine; i++) intNewLength += txtCodeBuilder.Lines[i].Length + 2;
            txtCodeBuilder.SelectionStart = intNewLength;
            Highlight_Selected_Code_Line();
        }

        /// <summary>
        /// Function to add Wait for move to complete code.
        /// </summary>
        private void Wait_For_Move_To_Complete()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Wait for Move To Complete Code. //" + System.Environment.NewLine;
            strCode += "isMoveComplete = false;" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("while (!isMoveComplete)" + System.Environment.NewLine);
            strCode += "{" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("	if (!GetMoveCompleteStatus(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            strCode += "}" + System.Environment.NewLine;
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add the beginner code to the source textbox for compiliation.
        /// </summary>
        private void Add_Code_To_Source_Textbox()
        {
            if (txtCodeBuilder.Text == String.Empty) return;

            tabControl1.SelectedTab = tabSourceCode;

            string[] strLines = txtCodeBuilder.Lines;
            int i = 0;

            // Add the necessary tabs.

            textSourceCode.Text = "public string Main(){" + System.Environment.NewLine;
            textSourceCode.Text += System.Environment.NewLine;
            for (i = 0; i < strLines.Length; i++) textSourceCode.Text += "	" + strLines[i] + System.Environment.NewLine;
            textSourceCode.Text += "	runNumber+=1;" + System.Environment.NewLine;
            textSourceCode.Text += "	return (robotOutput)" + ";" + System.Environment.NewLine;
            textSourceCode.Text += "}" + System.Environment.NewLine;
        }

        /// <summary>
        /// Function to delete the selected line of code.
        /// </summary>
        private void Delete_Selected_Line_Of_Code()
        {

            string[] strLines = txtCodeBuilder.Lines;
            int intStartLine = intCurCodeLine;

            if (strLines.Length == 0) return;

            if ((intCurCodeLine < 0) || (intCurCodeLine >= strLines.Length))
            {
                MessageBox.Show("Select Start of Code Block to be deleted");
                return;
            }

            int i = 0, intEndLine = -1, intNewCodeIndex = 0;

            intEndLine = Get_End_Line_Of_Code_Block(strLines, intCurCodeLine);
            if (intEndLine <= 0)
            {
                if (intEndLine == -2) MessageBox.Show("Select Start of Code Block to be deleted");
                else MessageBox.Show("Error Deleting Code!");
                return;
            }

            // Create a new string array to hold the modified code lines.
            string[] strNewCode = new string[(strLines.Length - (intEndLine - intCurCodeLine)) - 1];

            // Now fill in the new string array.
            for (i = 0; i < strLines.Length; i++)
            {
                if (i < intCurCodeLine || i > intEndLine)
                {
                    strNewCode[intNewCodeIndex] = strLines[i];
                    intNewCodeIndex += 1;
                }
            }

            // Update the text box with the new code.
            txtCodeBuilder.Lines = strNewCode;
            intCurCodeLine = intStartLine;
            txtCodeBuilder.Focus();
            int intNewLength = 0;
            for (i = 0; i < intStartLine; i++) intNewLength += strNewCode[i].Length + 2;
            txtCodeBuilder.SelectionStart = intNewLength;
            Highlight_Selected_Code_Line();
        }

        /// <summary>
        /// Function to get the end line for a selected code block.
        /// </summary>
        /// <param name="strLines"></param>
        /// <returns></returns>
        private int Get_End_Line_Of_Code_Block(string[] strLines, int intLine)
        {

            char[] chrTmp;
            int intCount = 0, i = 0, j = 0, intEndLine = -1;
            bool bFoundEndofLine = false;

            //MessageBox.Show("intLine = " + intLine.ToString());
            //MessageBox.Show("strLines.Length = " + strLines.Length.ToString());

            // Check to see if the currently selected line is the starting comment for this code block.
            chrTmp = strLines[intLine].ToCharArray();
            for (i = 0; i < chrTmp.Length; i++)
            {
                if (chrTmp[i] == '/') intCount += 1;
            }

            if (intCount < 4)
            {
                return (-2);
            }

            // Check the remaining lines of code until the end comment is located.
            for (i = intLine + 1; i < strLines.Length; i++)
            {
                chrTmp = strLines[i].ToCharArray();
                for (j = 0; j < chrTmp.Length; j++)
                {
                    if (chrTmp[j] == '/')
                    {
                        intEndLine = i;
                        bFoundEndofLine = true;
                        break;
                    }
                }
                if (bFoundEndofLine) break;
            }

            return (intEndLine);
        }

        /// <summary>
        /// Function to add get the A/D readings code.
        /// </summary>
        private void Get_AD_Readings()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Analog to Digital Sensor Readings Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetAnalogToDigitalSensorReadings(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Get Wheel Encoder code.
        /// </summary>
        private void Get_Wheel_Encoders()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Encoder Readings Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetWheelEncoderReadings(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add GetRFID code.
        /// </summary>
        private void Get_ASCII_RFID_Reading()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get ASCII RFID Reading Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetAsciiRFID(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add GetRFIDRaw reading code.
        /// </summary>
        private void Get_Hex_RFID_Reading()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Hex RFID Reading Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetHexRFID(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Get Wheel Velocity code.
        /// </summary>
        private void Get_Wheel_Velocities()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Wheel Velocities Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetWheelVelocities(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Is Reflex Triggered code.
        /// </summary>
        private void Is_Reflex_Triggered()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Reflex Triggered Status Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!GetReflexTriggeredStatus(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Print Sensor Readings code.
        /// </summary>
        private void Print_Sensor_Readings()
        {
            string strCode = String.Empty;
            bool bPrevChecked = false;

            // If none of the sensor boxes are checked then exit.
            if (!(ckbRunNum.Checked || ckbBATTreflex.Checked || ckbFCIRreflex.Checked || ckbFLIRreflex.Checked ||
                ckbFRIRreflex.Checked || ckbRLIRreflex.Checked || ckbRRIRreflex.Checked ||
                ckbFRLreflex.Checked || ckbFLLreflex.Checked || ckbEncoders.Checked ||
                ckbRFID.Checked || ckbVelocities.Checked)) return;

            // Add the code comment.
            strCode += "// User Print Sensor Readings Code. //" + System.Environment.NewLine;
            strCode += "robotOutput = ";

            if (ckbRunNum.Checked)
            {
                strCode += "Print(" + '"' + "RUN_NUM" + '"' + ")";
                bPrevChecked = true;
            }

            if (ckbBATTreflex.Checked && ckbFCIRreflex.Checked && ckbFLIRreflex.Checked &&
                ckbFRIRreflex.Checked && ckbRLIRreflex.Checked && ckbRRIRreflex.Checked &&
                ckbFRLreflex.Checked && ckbFLLreflex.Checked)
            {
                if (bPrevChecked) strCode += " + ";
                strCode += PadCodeWithSpaces("Print(" + '"' + "ALL_AD_SENSORS" + '"' + ")");
            }
            else
            {
                if (ckbBATTreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "BATT" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbFCIRreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "FCIR" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbFLIRreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "FLIR" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbFRIRreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "FRIR" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbRLIRreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "RLIR" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbRRIRreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "RRIR" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbFRLreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "FRL" + '"' + ")");
                    bPrevChecked = true;
                }
                if (ckbFLLreflex.Checked)
                {
                    if (bPrevChecked) strCode += " + ";
                    strCode += PadCodeWithSpaces("Print(" + '"' + "FLL" + '"' + ")");
                    bPrevChecked = true;
                }
            }

            if (ckbEncoders.Checked)
            {
                if (bPrevChecked) strCode += " + ";
                strCode += PadCodeWithSpaces("Print(" + '"' + "ENCODERS" + '"' + ")");
                bPrevChecked = true;
            }
            if (ckbVelocities.Checked)
            {
                if (bPrevChecked) strCode += " + ";
                strCode += PadCodeWithSpaces("Print(" + '"' + "VELOCITIES" + '"' + ")");
                bPrevChecked = true;
            }
            if (ckbRFID.Checked)
            {
                if (bPrevChecked) strCode += " + ";
                strCode += PadCodeWithSpaces("Print(" + '"' + "RFID" + '"' + ")");
                bPrevChecked = true;
            }
            strCode += ";" + System.Environment.NewLine;

            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Set A/D Reflex Level code.
        /// </summary>
        private void Set_AD_Reflex_Level()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Set A/D Reflex Level Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!SetADReflexLevel(" + nmbReflexLevel.Value.ToString() + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Set Light Reflex Level code.
        /// </summary>
        private void Set_Light_Reflex_Level()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Set Light Reflex Level Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!SetLightReflexLevel(" + nmbReflexLevel.Value.ToString() + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to add Set Sensory Reflexes code.
        /// </summary>
        private void Set_Sensory_Reflexes()
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            string strBinaryCode = String.Empty;
            char chrQuote = '"';

            if (ckbBATTreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbFCIRreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbFLIRreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbFRIRreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbRLIRreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbRLIRreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbFRLreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            if (ckbFLLreflex.Checked) strBinaryCode += "1";
            else strBinaryCode += "0";

            // Add the code comment.
            strCode += "// User Set Sensory Reflexes Code. //" + System.Environment.NewLine;
            strCode += PadCodeWithSpaces("if (!SetSensoryReflexes(" + chrQuote + strBinaryCode + chrQuote + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        /// <summary>
        /// Function to highlight the selected line of code.
        /// </summary>
        private void Highlight_Selected_Code_Line()
        {
            int intSelectStart = txtCodeBuilder.SelectionStart, intTmp = 0;
            int intStart = 0, intLength = 0;
            string[] strLines = txtCodeBuilder.Lines;

            for (int i = 0; i < strLines.Length; i++)
            {
                if (intSelectStart - i <= strLines[i].Length + intTmp + 1)
                {
                    intCurCodeLine = i;
                    intStart = intTmp + i;
                    intLength = strLines[i].Length + 1;
                    txtCodeBuilder.SelectionStart = intStart;
                    txtCodeBuilder.SelectionLength = intLength;
                    return;
                }
                intTmp += strLines[i].Length + 1;
            }
        }

        /// <summary>
        /// Function to add blank spaces to a line of code, so that it is easier to read.
        /// </summary>
        /// <param name="lineOfCode">String containing line of code to pad.</param>
        /// <returns>String containing padded line if code.</returns>
        private string PadCodeWithSpaces(string lineOfCode)
        {
            string paddedLineOfCode = string.Empty;

            char[] arrayOfChars = lineOfCode.ToCharArray();

            for (int charIndex = 0; charIndex < arrayOfChars.Length; charIndex++)
            {
                char tmpChar = arrayOfChars[charIndex];

                if (tmpChar == '(') paddedLineOfCode += tmpChar + " ";
                else if (tmpChar == ')') paddedLineOfCode += " " + tmpChar;
                else if (tmpChar == ',') paddedLineOfCode += tmpChar + " ";
                else if (tmpChar == '>') paddedLineOfCode += " " + tmpChar + " ";
                else if (tmpChar == '<') paddedLineOfCode += " " + tmpChar + " ";
                else if (tmpChar == '|')
                {
                    if (arrayOfChars[charIndex - 1] != '|') paddedLineOfCode += " " + tmpChar;
                    else paddedLineOfCode += tmpChar + " ";
                }
                else if (tmpChar == '&')
                {
                    if (arrayOfChars[charIndex - 1] != '&') paddedLineOfCode += " " + tmpChar;
                    else paddedLineOfCode += tmpChar + " ";
                }
                else paddedLineOfCode += tmpChar;
            }

            return paddedLineOfCode;
        }

        /// <summary>
        /// Exit Menu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuFile_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// New Menu Item. Creates new code.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuFile_New_Click(object sender, EventArgs e)
        {
            if (bSourceOpen && bCodeChanged) if (!Ask_User_To_Save()) return;
            textSourceCode.Text = "public string Main(){" + System.Environment.NewLine;
            textSourceCode.Text += "//Add Your Code Here" + System.Environment.NewLine;
            textSourceCode.Text += "return " + '"' + "test string" + '"' + ";" + System.Environment.NewLine;
            textSourceCode.Text += "}" + System.Environment.NewLine;
            bSourceOpen = true;
            bCodeChanged = true;
            strFileName = String.Empty;
            OpenRobotEngine.ActiveForm.Text = "Open-Robot Code Engine";
        }

        private void mnuFile_Open_Click(object sender, EventArgs e)
        {
            if (bSourceOpen && bCodeChanged) if (!Ask_User_To_Save()) return;
            if (openFileDialog1.ShowDialog().ToString() == "Cancel") return;

            strFileName = openFileDialog1.FileName;

            string strTmp = "";
            try
            {
                StreamReader fi = new StreamReader(strFileName, Encoding.Default);
                strTmp = fi.ReadToEnd();
                fi.Close();
            }
            catch (Exception fe)
            {
                MessageBox.Show(fe.Message);
                return;
            }

            if (!bBeginnerMode)
            {
                textSourceCode.Text = strTmp;
                OpenRobotEngine.ActiveForm.Text = "Open-Robot Code Engine: " + strFileName;
                bCodeChanged = false;
                tabControl1.SelectedTab = tabSourceCode;
            }
            else	// Check to make sure it is beginner code.
            {
                txtCodeBuilder.Text = strTmp;
                string[] strTemp = txtCodeBuilder.Lines;
                int intNullCount = 0, intEndLine = 0, intIndex = 0, i = 0;

                for (i = 0; i < strTemp.Length; i++) if (strTemp[i] == "") intNullCount += 1;

                string[] strSourceCode = new string[strTemp.Length - intNullCount];

                for (i = 0; i < strTemp.Length; i++)
                {
                    if (strTemp[i] != "")
                    {
                        strSourceCode[intIndex] = strTemp[i];
                        intIndex += 1;
                    }
                }

                // Need to go through source code to verify that it is in beginner code format.
                intIndex = 0;
                while ((intEndLine < strSourceCode.Length) && !(intIndex > strSourceCode.Length))
                {
                    intEndLine = Get_End_Line_Of_Code_Block(strSourceCode, intEndLine);
                    if (intEndLine <= 0)
                    {
                        MessageBox.Show("This Code is not in Begginer Format and will be unloaded.");
                        txtCodeBuilder.Text = String.Empty;
                        return;
                    }
                    intEndLine += 1;
                    intIndex += 1;
                }
                txtCodeBuilder.Lines = strSourceCode;
                txtCodeBuilder.Text += System.Environment.NewLine;
                tabControl1.SelectedTab = tabCodeBuilder;
            }

            bSourceOpen = true;
            bCodeChanged = false;
        }

        private void mnuFile_SaveAs_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog().ToString() == "Cancel") return;
            strFileName = saveFileDialog1.FileName;
            Save_Code(strFileName);
        }

        private void mnuFile_Save_Click(object sender, EventArgs e)
        {
            if (bSourceOpen && File.Exists(strFileName)) Save_Code(strFileName);
            else
            {
                if (saveFileDialog1.ShowDialog().ToString() == "Cancel") return;
                strFileName = saveFileDialog1.FileName;
                Save_Code(strFileName);
            }
        }

        private void mnuFile_SaveRobotOutput_Click(object sender, EventArgs e)
        {
            if (txtRobotOutput.Text == String.Empty) return;

            if (saveFileDialog1.ShowDialog().ToString() == "Cancel") return;
            string strRobotFile = saveFileDialog1.FileName;

            try
            {
                StreamWriter fi = new StreamWriter(strRobotFile, false, Encoding.Default);
                fi.Write(txtRobotOutput.Text);
                fi.Close();
            }
            catch (Exception fe)
            {
                MessageBox.Show(fe.Message);
                return;
            }
        }

        private void textSourceCode_TextChanged(object sender, EventArgs e)
        {
            bCodeChanged = true;
        }

        private void mnuCode_Compile_Click(object sender, EventArgs e)
        {
            if (textSourceCode.Text.Length < 1) return;
            try
            {
                txtErrors.Text = String.Empty;
                DoCompile();		// compile the C# source
                mnuCode_Load.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Compile+Run failed!", MessageBoxButtons.OK);
            }
        }

        private void mnuCode_Load_Click(object sender, EventArgs e)
        {
            //First Check to see if the dll exists!
            if (!File.Exists(strAppDir + "\\RobotAssembly.dll"))
            {
                MessageBox.Show("RobotAssembly.dll doesn't exist!", "Missing RobotAssembly.dll file!");
                mnuCode_Load.Enabled = false;
                mnuCode_Compile.Enabled = true;
                return;
            }

            secDom = AppDomain.CreateDomain("SecondaryDomain");
            factory = (LiveInterfaceFactory)secDom.CreateInstance("LiveInterface", "LiveCode.LiveInterface.LiveInterfaceFactory").Unwrap();
            ilive = factory.Create(strAppDir + "\\RobotAssembly.dll", "LiveCode.LiveSample.LiveClass", null);
            mnuRobotConnect.Enabled = true;
            mnuCode_Load.Enabled = false;
            mnuCode_Compile.Enabled = false;
            mnuCode_Unload.Enabled = true;
            mnuCode_Run.Enabled = true;
            mnuCode_Halt.Enabled = true;
            mnuFuzzyLogic.Enabled = true;
            secDomainLoaded = true;
            txtRobotOutput.Text = String.Empty;
            AddErrorText("Code Loaded");
        }

        private void mnuCode_Unload_Click(object sender, EventArgs e)
        {
            Unload_AppDomain();
            AddErrorText("Code Unloaded");
        }

        private void mnuCode_Run_Click(object sender, EventArgs e)
        {
            if (!bRobotConnected)
            {
                MessageBox.Show("Connect to robot!");
                return;
            }

            stopRobot = false;
            mnuCode_Halt.Enabled = true;
            mnuCode_Run.Enabled = false;
            mnuCode_Unload.Enabled = false;

            trdRobot = new Thread(new ThreadStart(this.RunRobotThreadTask));
            trdRobot.IsBackground = true;
            trdRobot.Start();

            AddErrorText("Code Running");
            tabControl1.SelectedTab = tabRobotData;
        }

        private void mnuCode_Halt_Click(object sender, EventArgs e)
        {
            stopRobot = true;
        }

        private void mnuFuzzyLogic_SetupFIS_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog().ToString() == "Cancel") return;

            string strPath = openFileDialog1.FileName;

            try
            {
                string strErrors = ilive.SetupFuzzyLib(strPath);
                if (strErrors != "OK")
                {
                    AddErrorText("FIS Setup failed!");
                    AddErrorText(strErrors);
                }
                else AddErrorText("FIS Setup");
            }
            catch (Exception ex)
            {
                AddErrorText("FIS Setup failed!");
                AddErrorText(ex.Message);
            }
        }

        private void rdoFullCode_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoFullCode.Checked)
            {
                Populate_Full_Code();
                rtfFullCode.Visible = true;
            }
            else rtfFullCode.Visible = false;
        }

        private void rdoUserCode_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoUserCode.Checked) textSourceCode.Visible = true;
            else textSourceCode.Visible = false;
        }

        private void mnuUserLevel_Beginner_Click(object sender, EventArgs e)
        {
            mnuUserLevel_Beginner.Checked = true;
            mnuUserLevel_Advanced.Checked = false;
            textSourceCode.ReadOnly = true;
            txtCodeBuilder.ReadOnly = true;
            mnuFile_New.Enabled = false;
            bBeginnerMode = true;
            mnuFuzzyLogic.Enabled = false;
            tabControl1.SelectedIndex = 0;
        }

        private void mnuUserLevel_Advanced_Click(object sender, EventArgs e)
        {
            /*PasswordForm inputPassword = new PasswordForm();
			inputPassword.ShowDialog();
			string strPassWord = inputPassword.PasswordResponse;
			if (strPassWord!="openrobot")
			{
				MessageBox.Show("Incorrect Password!","Password Error");
				return;
			}*/

            mnuUserLevel_Beginner.Checked = false;
            mnuUserLevel_Advanced.Checked = true;
            textSourceCode.ReadOnly = false;
            mnuFile_New.Enabled = true;
            bBeginnerMode = false;
            tabControl1.SelectedIndex = 1;
        }

        private void bAddMotionCode_Click(object sender, EventArgs e)
        {
            string strMotionCode = String.Empty, strPreceedingLogical = String.Empty, strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;
            bool bPreceedingLogical = false;

            // Add the code comment.
            strCode += "// User Motion Code. //" + System.Environment.NewLine;

            if (nmbLeftWheel.Value != 0 || nmbRightWheel.Value != 0)
            {
                if (rdoPositionControl.Checked)
                    strMotionCode += PadCodeWithSpaces("if (!MoveToPosition(" + nmbLeftWheel.Value.ToString() + "," + nmbRightWheel.Value.ToString() + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
                else if (rdoClosedLoopControl.Checked)
                    strMotionCode = PadCodeWithSpaces("if (!SetClosedLoopVelocity(" + nmbLeftWheel.Value.ToString() + "," + nmbRightWheel.Value.ToString() + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
                else if (rdoOpenLoopControl.Checked)
                    strMotionCode = PadCodeWithSpaces("if (!SetOpenLoopVelocity(" + nmbLeftWheel.Value.ToString() + "," + nmbRightWheel.Value.ToString() + "," + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine);
            }
            else
            {
                strMotionCode = PadCodeWithSpaces("if (!StopRobot(" + timeOutms + "," + numRetries + ")) return (robotOutput);" + System.Environment.NewLine);
            }

            if (rdoIfMotionComplete.Checked)
            {
                if (ckbInsertAsElseIf.Checked) strCode += PadCodeWithSpaces("else if (isMoveComplete)" + System.Environment.NewLine);
                else strCode += PadCodeWithSpaces("if (isMoveComplete)" + System.Environment.NewLine);
                strCode += "{" + System.Environment.NewLine;
                strCode += "	" + strMotionCode;
                strCode += "}" + System.Environment.NewLine;
            }
            else if (rdoIfMotionNotComplete.Checked)
            {
                if (ckbInsertAsElseIf.Checked) strCode += PadCodeWithSpaces("else if (!isMoveComplete)" + System.Environment.NewLine);
                else strCode += PadCodeWithSpaces("if (!isMoveComplete)" + System.Environment.NewLine);
                strCode += "{" + System.Environment.NewLine;
                strCode += "	" + strMotionCode;
                strCode += "}" + System.Environment.NewLine;
            }
            else if (rdoIfReflexNotTriggered.Checked)
            {
                if (ckbInsertAsElseIf.Checked) strCode += PadCodeWithSpaces("else if (!isReflexTriggered)" + System.Environment.NewLine);
                else strCode += PadCodeWithSpaces("if (!isReflexTriggered)" + System.Environment.NewLine);
                strCode += "{" + System.Environment.NewLine;
                strCode += "	" + strMotionCode;
                strCode += "}" + System.Environment.NewLine;
            }
            else if (rdoIfReflexTriggered.Checked)
            {
                if (ckbInsertAsElseIf.Checked) strCode += PadCodeWithSpaces("else if (isReflexTriggered)" + System.Environment.NewLine);
                else strCode += PadCodeWithSpaces("if (isReflexTriggered)" + System.Environment.NewLine);
                strCode += "{" + System.Environment.NewLine;
                strCode += "	" + strMotionCode;
                strCode += "}" + System.Environment.NewLine;
            }
            else if (rdoNoConditionals.Checked)
            {
                strCode += strMotionCode;
            }
            else if (rdoIfCheckedAD.Checked)
            {
                if (ckbInsertAsElseIf.Checked) strCode += "else if (";
                else strCode += "if (";
                if (ckbBATT.Checked)
                {
                    if (ckbBATTlogical.Checked) strCode += "BATT>" + nmbBATT.Value.ToString();
                    else strCode += "BATT<" + nmbBATT.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbBATTand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbFCIR.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbFCIRlogical.Checked) strCode += "FCIR>" + nmbFCIR.Value.ToString();
                    else strCode += "FCIR<" + nmbFCIR.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbFCIRand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbFLIR.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbFLIRlogical.Checked) strCode += "FLIR>" + nmbFLIR.Value.ToString();
                    else strCode += "FLIR<" + nmbFLIR.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbFLIRand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbFRIR.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbFRIRlogical.Checked) strCode += "FRIR>" + nmbFRIR.Value.ToString();
                    else strCode += "FRIR<" + nmbFRIR.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbFRIRand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbRLIR.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbRLIRlogical.Checked) strCode += "RLIR>" + nmbRLIR.Value.ToString();
                    else strCode += "RLIR<" + nmbRLIR.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbRLIRand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbRRIR.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbRRIRlogical.Checked) strCode += "RRIR>" + nmbRRIR.Value.ToString();
                    else strCode += "RRIR<" + nmbRRIR.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbRRIRand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbFRL.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbFRLlogical.Checked) strCode += "FRL>" + nmbFRL.Value.ToString();
                    else strCode += "FRL<" + nmbFRL.Value.ToString();
                    bPreceedingLogical = true;
                    if (ckbFRLand.Checked) strPreceedingLogical = "&&";
                    else strPreceedingLogical = "||";
                }

                if (ckbFLL.Checked)
                {
                    if (bPreceedingLogical) strCode += strPreceedingLogical;
                    if (ckbFLLlogical.Checked) strCode += "FLL>" + nmbFLL.Value.ToString();
                    else strCode += "FLL<" + nmbFLL.Value.ToString();
                }

                strCode = PadCodeWithSpaces(strCode);

                strCode += ")" + System.Environment.NewLine;
                strCode += "{" + System.Environment.NewLine;
                strCode += "	" + strMotionCode;
                strCode += "}" + System.Environment.NewLine;
            }

            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        private void bIsMoveComplete_Click(object sender, EventArgs e)
        {
            string strCode = String.Empty;
            string timeOutRetry = timeOutms + "," + numRetries;

            // Add the code comment.
            strCode += "// User Get Move Complete Status Code. //" + System.Environment.NewLine;
            strCode += "if (!GetMoveCompleteStatus(" + timeOutRetry + ")) return (robotOutput);" + System.Environment.NewLine;
            // Complete the code comment.
            strCode += "//" + System.Environment.NewLine;
            // Insert the new code.
            Insert_Code(strCode);
        }

        private void bClearMotionCheckBoxes_Click(object sender, EventArgs e)
        {
            ckbBATT.Checked = false;
            ckbBATTlogical.Checked = false;
            ckbBATTand.Checked = false;

            ckbFCIR.Checked = false;
            ckbFCIRlogical.Checked = false;
            ckbFCIRand.Checked = false;

            ckbFLIR.Checked = false;
            ckbFLIRlogical.Checked = false;
            ckbFLIRand.Checked = false;

            ckbFRIR.Checked = false;
            ckbFRIRlogical.Checked = false;
            ckbFRIRand.Checked = false;

            ckbRLIR.Checked = false;
            ckbRLIRlogical.Checked = false;
            ckbRLIRand.Checked = false;

            ckbRRIR.Checked = false;
            ckbRRIRlogical.Checked = false;
            ckbRRIRand.Checked = false;

            ckbFRL.Checked = false;
            ckbFRLlogical.Checked = false;
            ckbFRLand.Checked = false;

            ckbFLL.Checked = false;
            ckbFLLlogical.Checked = false;
        }

        private void bCheckMotionCheckBoxes_Click(object sender, EventArgs e)
        {
            ckbBATT.Checked = true;
            ckbBATTlogical.Checked = true;
            ckbBATTand.Checked = true;

            ckbFCIR.Checked = true;
            ckbFCIRlogical.Checked = true;
            ckbFCIRand.Checked = true;

            ckbFLIR.Checked = true;
            ckbFLIRlogical.Checked = true;
            ckbFLIRand.Checked = true;

            ckbFRIR.Checked = true;
            ckbFRIRlogical.Checked = true;
            ckbFRIRand.Checked = true;

            ckbRLIR.Checked = true;
            ckbRLIRlogical.Checked = true;
            ckbRLIRand.Checked = true;

            ckbRRIR.Checked = true;
            ckbRRIRlogical.Checked = true;
            ckbRRIRand.Checked = true;

            ckbFRL.Checked = true;
            ckbFRLlogical.Checked = true;
            ckbFRLand.Checked = true;

            ckbFLL.Checked = true;
            ckbFLLlogical.Checked = true;
        }

        private void txtCodeBuilder_MouseUp(object sender, MouseEventArgs e)
        {
            Highlight_Selected_Code_Line();
        }

        private void bAddSensorControlCode_Click(object sender, EventArgs e)
        {
            int intIndex = cmbSensorControls.SelectedIndex;

            if (intIndex < 0) return;

            switch (intIndex)
            {
                case 0:
                    Get_AD_Readings();
                    break;
                case 1:
                    Get_Wheel_Encoders();
                    break;
                case 2:
                    Get_ASCII_RFID_Reading();
                    break;
                case 3:
                    Get_Hex_RFID_Reading();
                    break;
                case 4:
                    Get_Wheel_Velocities();
                    break;
                case 5:
                    Is_Reflex_Triggered();
                    break;
                case 6:
                    Print_Sensor_Readings();
                    break;
                case 7:
                    Set_AD_Reflex_Level();
                    break;
                case 8:
                    Set_Light_Reflex_Level();
                    break;
                case 9:
                    Set_Sensory_Reflexes();
                    break;
                case 10:
                    Wait_For_Move_To_Complete();
                    break;
                default:
                    break;
            }
        }

        private void bExecuteAdditionalFunction_Click(object sender, EventArgs e)
        {
            int intIndex = cmbAdditionalCodeFunction.SelectedIndex;

            if (intIndex < 0) return;

            switch (intIndex)
            {
                case 0:
                    Delete_Selected_Line_Of_Code();
                    break;
                default:
                    break;
            }
        }

        private void txtCodeBuilder_TextChanged(object sender, EventArgs e)
        {
            bCodeChanged = true;
            bSourceOpen = true;
        }

        private void bAddCodeToSourceTextbox_Click(object sender, EventArgs e)
        {
            Add_Code_To_Source_Textbox();
        }

        private void txtCodeBuilder_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode.ToString().ToUpper())
            {
                case "DELETE":
                    Delete_Selected_Line_Of_Code();
                    break;
                default:
                    break;
            }
        }

        private void mnuAboutOpenRobotEngine_Click(object sender, EventArgs e)
        {
            string strAbout = String.Empty;

            strAbout = "The Open-Robot Engine was created so that" + System.Environment.NewLine;
            strAbout += "users of all skill levels would have access " + System.Environment.NewLine;
            strAbout += "to a development tool that can be used to" + System.Environment.NewLine;
            strAbout += "create programs for their robot." + System.Environment.NewLine;
            strAbout += System.Environment.NewLine;
            strAbout += "Created and designed by Abraham L. Howell." + System.Environment.NewLine;

            MessageBox.Show(strAbout, "About Open-Robot Engine");
        }

        private void mnuRobotConnect_Click(object sender, EventArgs e)
        {
            try
            {
                //Open the robot TCP/IP connection.
                ilive.ConnectToRobot(txtRobotIP.Text, 10001);

                bRobotConnected = true;
                mnuCode_Run.Enabled = true;
                mnuRobotConnect.Enabled = false;
                mnuRobotDisconnect.Enabled = true;
                AddErrorText("IP Address " + txtRobotIP.Text + " Open");
            }
            catch (Exception ex)
            {
                AddErrorText(ex.Message);
                return;
            }
        }

        private void mnuRobotDisconnect_Click(object sender, EventArgs e)
        {
            if (bRobotConnected)
            {
                ilive.DisconnectFromRobot();
            }
            bRobotConnected = false;
            mnuRobotDisconnect.Enabled = false;
            mnuRobotConnect.Enabled = true;
            AddErrorText("Disconnected from Robot IP Address: " + txtRobotIP.Text);
        }

        private void nmbTimeOutms_ValueChanged(object sender, EventArgs e)
        {
            timeOutms = Convert.ToInt16(nmbTimeOutms.Value);
        }

        private void nmbNumRetries_ValueChanged(object sender, EventArgs e)
        {
            numRetries = Convert.ToInt16(nmbNumRetries.Value);
        }      

    }
}